{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/nceder/qpb4e/blob/main/code/Chapter%2018/Chapter_18.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 18. Packages"
      ],
      "metadata": {
        "id": "PY8jjVh-NErJ"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 18.3 Implementing the mathproj package"
      ],
      "metadata": {
        "id": "Slvy4720NdS6"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# create package directory structure\n",
        "! mkdir mathproj\n",
        "! mkdir mathproj/comp\n",
        "! mkdir mathproj/comp/numeric\n"
      ],
      "metadata": {
        "id": "UZwPtA1ZRkuy"
      },
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "open(\"mathproj/__init__.py\", \"w\").write(\"\"\"print(\"Hello from mathproj init\")\n",
        "__all__ = ['comp']\n",
        "version = 1.03\"\"\")\n",
        "\n",
        "open(\"mathproj/comp/__init__.py\", \"w\").write(\"\"\"__all__ = ['c1']\n",
        "print(\"Hello from mathproj.comp init\")\"\"\")\n",
        "open(\"mathproj/comp/numeric/__init__.py\", \"w\").write(\"\"\"print(\"Hello from numeric init\")\"\"\")\n",
        "open(\"mathproj/comp/c1.py\", \"w\").write(\"\"\"x = 1.00\"\"\")\n",
        "open(\"mathproj/comp/numeric/n1.py\", \"w\").write(\"\"\"# File mathproj/comp/numeric/n1.py\n",
        "\n",
        "from mathproj import version\n",
        "from mathproj.comp import c1\n",
        "from mathproj.comp.numeric.n2 import h\n",
        "def g():\n",
        "    print(\"version is\", version)\n",
        "    print(h())  \"\"\")\n",
        "open(\"mathproj/comp/numeric/n2.py\", \"w\").write(\"\"\"def h():\n",
        "    return \"Called function h in module n2\"\n",
        "\"\"\")"
      ],
      "metadata": {
        "id": "DHoAH64daLHJ"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile mathproj/__init__.py\n",
        "# File mathproj/__init__.py\n",
        "\n",
        "print(\"Hello from mathproj init\")\n",
        "__all__ = ['comp']\n",
        "version = 1.03"
      ],
      "metadata": {
        "id": "9vhuVTwpNNZb",
        "outputId": "f0828c1c-3f85-4d35-b770-e4681f47c11d",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing mathproj/__init__.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile mathproj/comp/__init__.py\n",
        "# File mathproj/comp/__init__.py\n",
        "\n",
        "__all__ = ['c1']\n",
        "print(\"Hello from mathproj.comp init\")"
      ],
      "metadata": {
        "id": "uuM4tXDUNNl6",
        "outputId": "edc7a72f-b09e-4a62-fbd4-9e4f5e7e0291",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing mathproj/comp/__init__.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile mathproj/comp/c1.py\n",
        "# File mathproj/comp/c1.py\n",
        "\n",
        "x = 1.00"
      ],
      "metadata": {
        "id": "hQbr-xgNNNp2",
        "outputId": "10cfaf66-4077-494b-f3de-e2615e6a294f",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing mathproj/comp/c1.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile mathproj/comp/numeric/__init__.py\n",
        "# File mathproj/comp/numeric/__init__.py\n",
        "\n",
        "print(\"Hello from numeric init\")"
      ],
      "metadata": {
        "id": "yfB2WOmANNtS",
        "outputId": "1ef54783-eaef-4030-b76c-412c10c7a98c",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing mathproj/comp/numeric/__init__.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile mathproj/comp/numeric/n1.py\n",
        "# File mathproj/comp/numeric/n1.py\n",
        "\n",
        "from mathproj import version\n",
        "from mathproj.comp import c1\n",
        "from mathproj.comp.numeric.n2 import h\n",
        "def g():\n",
        "    print(\"version is\", version)\n",
        "    print(h())"
      ],
      "metadata": {
        "id": "jNmtWtrdNNxJ",
        "outputId": "00aa8f96-354e-4ddd-932b-de03a7fdd5dd",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing mathproj/comp/numeric/n1.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile mathproj/comp/numeric/n2.py\n",
        "# File mathproj/comp/numeric/n2.py\n",
        "\n",
        "def h():\n",
        "    return \"Called function h in module n2\""
      ],
      "metadata": {
        "id": "75zvlxQCNN0j",
        "outputId": "8557eae1-7ec3-4e92-8fff-2362c599b4f5",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing mathproj/comp/numeric/n2.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 18.3.2 Basic use of the mathproj package"
      ],
      "metadata": {
        "id": "1Xa5ZwRAMohY"
      }
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1OxVpde9MEaG",
        "outputId": "b2b04f49-ef6c-4f63-dca3-54e6077f2ca7",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "import mathproj"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Hello from mathproj init\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "694X2FQ0MEaI",
        "outputId": "7f064196-355e-4909-ae4c-aaa6076e9d9e",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "mathproj.version"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "1.03"
            ]
          },
          "metadata": {},
          "execution_count": 10
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 18.3.3 Loading subpackages and submodules"
      ],
      "metadata": {
        "id": "ZeQ7KvvnfEfX"
      }
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "HJrJA7H1MEaJ",
        "outputId": "2b920d6f-b8db-4a86-d457-7d995fb82b4e",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 141
        }
      },
      "source": [
        "mathproj.comp.numeric.n1"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "error",
          "ename": "AttributeError",
          "evalue": "module 'mathproj' has no attribute 'comp'",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-11-1f477095b948>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmathproj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcomp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnumeric\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;31mAttributeError\u001b[0m: module 'mathproj' has no attribute 'comp'"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OQltADMyMEaJ",
        "outputId": "d3668e27-1692-49d8-94e3-15355a78ec9e",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "import mathproj.comp.numeric.n1"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Hello from mathproj.comp init\n",
            "Hello from numeric init\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ZPsBE4p6MEaJ",
        "outputId": "be8b0236-539f-4d0a-a983-75941cb84e27",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "mathproj.comp.numeric.n1.g()"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "version is 1.03\n",
            "Called function h in module n2\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zgsK5uOBMEaK",
        "outputId": "02f99b9a-a264-4b4d-aaf6-464e4da5ee84",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "mathproj.comp"
      ],
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<module 'mathproj.comp' from '/content/mathproj/comp/__init__.py'>"
            ]
          },
          "metadata": {},
          "execution_count": 14
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "n-fb-GRdMEaK",
        "outputId": "36097bed-994c-4916-db92-d75e829a88d1",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "mathproj.comp.numeric"
      ],
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<module 'mathproj.comp.numeric' from '/content/mathproj/comp/numeric/__init__.py'>"
            ]
          },
          "metadata": {},
          "execution_count": 15
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 18.4 The `__all__` attribute"
      ],
      "metadata": {
        "id": "a7ep4uage460"
      }
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tYDwAg5AMEaL",
        "outputId": "f825e44d-5715-4529-f3a2-cffc2b08729a",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "# use the Runtime menu, and Restart session\n",
        "\n",
        "from mathproj import *"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Hello from mathproj init\n",
            "Hello from mathproj.comp init\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fxmdVe4sMEaL",
        "outputId": "a6764125-af8a-470a-ac00-f4f0d97db4bc",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "comp"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<module 'mathproj.comp' from '/content/mathproj/comp/__init__.py'>"
            ]
          },
          "metadata": {},
          "execution_count": 2
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9TN_L0eWMEaM",
        "outputId": "89ae7a9e-c0d5-4769-b50a-84fb66babafc",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 141
        }
      },
      "source": [
        "c1"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "error",
          "ename": "NameError",
          "evalue": "name 'c1' is not defined",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-3-5348681b35c2>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mc1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;31mNameError\u001b[0m: name 'c1' is not defined"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QVDnndHmMEaN",
        "outputId": "4e681a96-7e48-45a2-f09f-7c5fc9ccceab",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "from mathproj.comp import c1\n",
        "c1"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<module 'mathproj.comp.c1' from '/content/mathproj/comp/c1.py'>"
            ]
          },
          "metadata": {},
          "execution_count": 4
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Quick Check: Packages\n",
        "Suppose that you're writing a package that takes a URL, retrieves all images on the page pointed to by that URL, resizes them to a standard size, and stores them. Leaving aside the exact details of how each of these functions will be coded, how would you organize those features into a package?\n",
        "\n",
        "\n",
        "####Solution\n",
        "The package will be performing three types of actions: fetching a page and parsing the HTML for image URLs, fetching the images, and resizing the images. For this reason, you might consider having three modules to keep the actions separate:\n",
        "```python\n",
        "picture_fetch/\n",
        "    __init__.py\n",
        "    find.py\n",
        "    fetch.py\n",
        "    resize.py\n",
        "```"
      ],
      "metadata": {
        "id": "ziOf_xjrZVa7"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# 18.6 Lab 18: Create a package\n",
        "In chapter 14, you added error handling to the text cleaning and word frequency counting module that you created in chapter 10. Refactor that code into a package containing at least one module for the cleaning functions, and another for the processing functions, and (optionally) one for custom exceptions (if you have any). Then write a simple main function that uses all the modules in the package."
      ],
      "metadata": {
        "id": "3JDPm1k_v8vD"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!wget https://raw.githubusercontent.com/nceder/qpb4e/main/code/Chapter%2006/moby_01.txt &> null  && echo Downloaded"
      ],
      "metadata": {
        "id": "iNjyoFZebE37",
        "outputId": "b44cd064-7e83-4a9d-d8a2-02bb77c85351",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Downloaded\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Author's solution"
      ],
      "metadata": {
        "id": "-thTWKxtgMG2"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "! mkdir word_count"
      ],
      "metadata": {
        "id": "Ryxl8P24gQr_"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### `__init__.py`"
      ],
      "metadata": {
        "id": "vCoPsVwcgXFT"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_count/__init__.py\n",
        "#__init__.py\n",
        "\n",
        "from word_count.exceptions import EmptyStringError\n",
        "from word_count.cleaning import clean_line, get_words\n",
        "from word_count.counter import count_words, word_stats"
      ],
      "metadata": {
        "id": "scUQF9j2f8O0",
        "outputId": "8a48e640-0863-41cf-b187-256d51545e6e",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing word_count/__init__.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### `exceptions.py`"
      ],
      "metadata": {
        "id": "-vTBPh-QgiTP"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_count/exceptions.py\n",
        "# exceptions.py\n",
        "\n",
        "class EmptyStringError(Exception):\n",
        "    pass"
      ],
      "metadata": {
        "id": "T1eDDi0JgbNV",
        "outputId": "864f4eda-787f-43f1-f34d-239e56322e77",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing word_count/exceptions.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### `cleaning.py`"
      ],
      "metadata": {
        "id": "IHVgbSblgnrG"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_count/cleaning.py\n",
        "# cleaning.py\n",
        "\n",
        "from word_count.exceptions import EmptyStringError\n",
        "\n",
        "punct = str.maketrans(\"\",  \"\", \"!.,:;-?\")\n",
        "\n",
        "def clean_line(line):\n",
        "    \"\"\"changes case and removes punctuation\"\"\"\n",
        "\n",
        "    # raise exception if line is empty\n",
        "    # uncomment to test EmptyStringError\n",
        "    #if not line.strip():\n",
        "    #    raise EmptyStringError()\n",
        "\n",
        "    # make all one case\n",
        "    cleaned_line = line.lower()\n",
        "\n",
        "    # remove punctuation\n",
        "    cleaned_line = cleaned_line.translate(punct)\n",
        "    return cleaned_line\n",
        "\n",
        "\n",
        "def get_words(line):\n",
        "    \"\"\"splits line into words, and rejoins with newlines\"\"\"\n",
        "    words = line.split()\n",
        "    return \"\\n\".join(words) + \"\\n\""
      ],
      "metadata": {
        "id": "nI71Y8n-gta-",
        "outputId": "14620cb3-6c43-4356-fffa-314777e81ef1",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Overwriting word_count/cleaning.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### `counter.py`"
      ],
      "metadata": {
        "id": "MKLYznrZg86y"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_count/counter.py\n",
        "# counter.py\n",
        "\n",
        "def count_words(words):\n",
        "    \"\"\"takes list of cleaned words, returns count dictionary\"\"\"\n",
        "    word_count = {}\n",
        "    for word in words:\n",
        "        try:\n",
        "            count = word_count.setdefault(word, 0)\n",
        "        except TypeError:\n",
        "            #if 'word' is not hashable, skip to next word.\n",
        "            pass\n",
        "        word_count[word] += 1\n",
        "    return word_count\n",
        "\n",
        "\n",
        "def word_stats(word_count):\n",
        "    \"\"\"Takes word count dictionary, returns top and bottom five entries\"\"\"\n",
        "    word_list = list(word_count.items())\n",
        "    word_list.sort(key=lambda x: x[1])\n",
        "    try:\n",
        "        least_common = word_list[:5]\n",
        "        most_common = word_list[-1:-6:-1]\n",
        "    except IndexError as e:\n",
        "        # if list is empty or too short, just return list\n",
        "        least_common = word_list\n",
        "        most_common = list(reversed(word_list))\n",
        "\n",
        "    return most_common, least_common"
      ],
      "metadata": {
        "id": "FcgzXxmLhAC_",
        "outputId": "54ba7236-79bd-40be-9401-fa765b238366",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing word_count/counter.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Code to use package"
      ],
      "metadata": {
        "id": "QDPPJlzYhL5P"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import word_count\n",
        "\n",
        "if __name__ == \"__main__\":\n",
        "    with (open(\"moby_01.txt\") as infile,\n",
        "            open(\"moby_01_clean.txt\", \"w\") as outfile):\n",
        "        for line in infile:\n",
        "            cleaned_line = word_count.clean_line(line)\n",
        "\n",
        "            cleaned_words = word_count.get_words(cleaned_line)\n",
        "\n",
        "            # write all words for line\n",
        "            outfile.write(cleaned_words)\n",
        "\n",
        "    moby_words = []\n",
        "    with open('moby_01_clean.txt') as infile:\n",
        "        for word in infile:\n",
        "            if word.strip():\n",
        "                moby_words.append(word.strip())\n",
        "\n",
        "    word_counter = word_count.count_words(moby_words)\n",
        "\n",
        "    most, least = word_count.word_stats(word_counter)\n",
        "    print(\"Most common words:\")\n",
        "    for word in most:\n",
        "        print(word)\n",
        "    print(\"\\nLeast common words:\")\n",
        "    for word in least:\n",
        "        print(word)"
      ],
      "metadata": {
        "id": "WoUCRIzVhPxd",
        "outputId": "c973db0f-57d3-4521-e93a-2c1bd7fdf7a3",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Most common words:\n",
            "('the', 14)\n",
            "('i', 9)\n",
            "('and', 9)\n",
            "('of', 8)\n",
            "('is', 7)\n",
            "\n",
            "Least common words:\n",
            "('call', 1)\n",
            "('ishmael', 1)\n",
            "('years', 1)\n",
            "('ago', 1)\n",
            "('never', 1)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Copilot solution\n",
        "\n",
        "As mentioned in the text, the prompt needed some re-engineering to get Copilot to produce the desired code. The prompt and results below are the final working verisons.\n",
        "\n",
        "### Prompt\n",
        "\n",
        "Refactor the code in word_processing.py into a package containing at least one module for the cleaning functions, and another for the processing functions, and (optionally) one for custom exceptions (if you have any). Be sure to use the code from the original file to reproduce the functionality of the origibnal file. Then refactor main.py to use the new package.\n",
        "\n",
        "Supply the code for the clean_line and write_words_to_file functions."
      ],
      "metadata": {
        "id": "lYjNq2fshmyP"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "! mkdir word_processing"
      ],
      "metadata": {
        "id": "5YJJeMR1wxOW",
        "outputId": "3e25fde0-c72d-44c3-d198-a6e424c181d2",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "mkdir: cannot create directory ‘word_processing’: File exists\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### word_processing/cleaning.py"
      ],
      "metadata": {
        "id": "t7QRYeudiiqR"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_processing/cleaning.py\n",
        "\n",
        "import re\n",
        "\n",
        "def clean_line(line):\n",
        "    # Remove punctuation and convert to lowercase\n",
        "    line = re.sub(r'[^\\w\\s]', '', line)\n",
        "    line = line.lower()\n",
        "    return line"
      ],
      "metadata": {
        "id": "O7FNdGvmhdF4",
        "outputId": "61b34bc8-a8e5-4b55-eb28-d0554df76bc6",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing word_processing/cleaning.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### word_processing/processing.py"
      ],
      "metadata": {
        "id": "ZrVhoas9iseg"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_processing/processing.py\n",
        "\n",
        "def count_word_occurrences(words):\n",
        "    word_counts = {}\n",
        "    for word in words:\n",
        "        if word in word_counts:\n",
        "            word_counts[word] += 1\n",
        "        else:\n",
        "            word_counts[word] = 1\n",
        "    return word_counts\n",
        "\n",
        "def print_common_words(word_counts, n):\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "    print(f\"{n} most common words:\")\n",
        "    for word, count in sorted_word_counts[:n]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def print_least_common_words(word_counts, n):\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "    print(f\"{n} least common words:\")\n",
        "    for word, count in sorted_word_counts[-n:]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def write_words_to_file(words, output_file):\n",
        "    for word in words:\n",
        "        output_file.write(word + '\\n')\n",
        "\n",
        "def process_file(input_file_path, output_file_path):\n",
        "    with open(input_file_path, 'r') as input_file:\n",
        "        with open(output_file_path, 'w') as output_file:\n",
        "            for line in input_file:\n",
        "                cleaned_line = clean_line(line)\n",
        "                words = cleaned_line.split()\n",
        "                write_words_to_file(words, output_file)"
      ],
      "metadata": {
        "id": "gSiofzCIiw9v",
        "outputId": "c362cc2d-c2b7-48d4-f7f9-a53e10a20f05",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Overwriting word_processing/processing.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### word_processing/exceptions.py"
      ],
      "metadata": {
        "id": "maJwP_LMixx_"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_processing/exceptions.py\n",
        "\n",
        "# If you have any custom exceptions, define them here"
      ],
      "metadata": {
        "id": "NJ8n2v0Wi3Is",
        "outputId": "e8343b1c-0521-491b-96c4-ca45124662da",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing word_processing/exceptions.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### `__init__.py`"
      ],
      "metadata": {
        "id": "UxHwLKKJjfDD"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile word_processing/__init__.py\n",
        "\n",
        "from .cleaning import clean_line\n",
        "from .processing import (\n",
        "    count_word_occurrences,\n",
        "    print_common_words,\n",
        "    print_least_common_words,\n",
        "    write_words_to_file,\n",
        "    process_file\n",
        ")"
      ],
      "metadata": {
        "id": "_KTl6mv4jePW",
        "outputId": "caeb2f43-3e20-4b52-803a-6a003a83b3b2",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Overwriting word_processing/__init__.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### main.py"
      ],
      "metadata": {
        "id": "uNhY5Qhri3zb"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile main.py\n",
        "\n",
        "from word_processing import (\n",
        "    process_file,\n",
        "    count_word_occurrences,\n",
        "    print_common_words,\n",
        "    print_least_common_words\n",
        ")\n",
        "\n",
        "# Example usage\n",
        "input_file_path = 'input.txt'\n",
        "output_file_path = 'output.txt'\n",
        "\n",
        "process_file(input_file_path, output_file_path)\n",
        "\n",
        "# Assuming you have a list of words from somewhere\n",
        "words = [\"example\", \"words\", \"for\", \"testing\", \"example\", \"words\"]\n",
        "word_counts = count_word_occurrences(words)\n",
        "print_common_words(word_counts, 3)\n",
        "print_least_common_words(word_counts, 3)"
      ],
      "metadata": {
        "id": "FUfaYBQNi8uF",
        "outputId": "5afb92d4-5fe1-4423-e774-bf50e0989699",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing main.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!python main.py"
      ],
      "metadata": {
        "id": "IUlTh3-4x7kH",
        "outputId": "78efa61d-f7e8-47f5-8387-5dccae30ba7d",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Traceback (most recent call last):\n",
            "  File \"/content/main.py\", line 13, in <module>\n",
            "    process_file(input_file_path, output_file_path)\n",
            "  File \"/content/word_processing/processing.py\", line 28, in process_file\n",
            "    with open(input_file_path, 'r') as input_file:\n",
            "FileNotFoundError: [Errno 2] No such file or directory: 'input.txt'\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Colaboratory solution\n",
        "\n",
        "### Prompt\n",
        "\n",
        "Refactor the code in module created in cell above into a package containing at least one module for the cleaning functions, and another for the processing functions, and (optionally) one for custom exceptions (if you have any). Then refactor `main()` to use the new package."
      ],
      "metadata": {
        "id": "tFMLEqFAjr9W"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Code from chapter 10 solution to refactor"
      ],
      "metadata": {
        "id": "KtQW5BmFkdAA"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Generated by colaboratory\n",
        "# prompt: Package the functions in the cell above as a standalone module so that\n",
        "#         the module can be used by other code. Then write the code to use the\n",
        "#         module to achieve the same result as the cell above.\n",
        "\n",
        "# Save the functions as a module named \"text_processing.py\"\n",
        "with open(\"text_processing.py\", \"w\") as f:\n",
        "    f.write(r\"\"\"\n",
        "def clean_line(line):\n",
        "    # Convert the line to lowercase\n",
        "    line = line.lower()\n",
        "\n",
        "    # Remove punctuation from the line\n",
        "    line = line.translate(str.maketrans('', '', string.punctuation))\n",
        "\n",
        "    return line\n",
        "\n",
        "def write_words_to_file(words, output_file):\n",
        "    # Write each word to the output file\n",
        "    for word in words:\n",
        "        output_file.write(word + '\\n')\n",
        "\n",
        "def count_word_occurrences(words):\n",
        "    # Count the occurrences of each word using a dictionary\n",
        "    word_counts = {}\n",
        "    for word in words:\n",
        "        if word in word_counts:\n",
        "            word_counts[word] += 1\n",
        "        else:\n",
        "            word_counts[word] = 1\n",
        "\n",
        "    return word_counts\n",
        "\n",
        "def print_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n most common words and their occurrences\n",
        "    print(f\"{n} most common words:\")\n",
        "    for word, count in sorted_word_counts[:n]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def print_least_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n least common words and their occurrences\n",
        "    print(f\"{n} least common words:\")\n",
        "    for word, count in sorted_word_counts[-n:]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def process_file(input_file_path, output_file_path):\n",
        "    # Open the input file for reading\n",
        "    with open(input_file_path, 'r') as input_file:\n",
        "        # Open the output file for writing\n",
        "        with open(output_file_path, 'w') as output_file:\n",
        "            # Iterate over each line in the input file\n",
        "            for line in input_file:\n",
        "                # Clean the line\n",
        "                cleaned_line = clean_line(line)\n",
        "\n",
        "                # Split the line into words\n",
        "                words = cleaned_line.split()\n",
        "\n",
        "                # Write the words to the output file\n",
        "                write_words_to_file(words, output_file)\n",
        "\"\"\")\n",
        "\n",
        "# Use the module\n",
        "import text_processing\n",
        "\n",
        "input_file_path = 'moby_01.txt'\n",
        "output_file_path = 'moby_01_clean.txt'\n",
        "\n",
        "# Process the file\n",
        "text_processing.process_file(input_file_path, output_file_path)\n",
        "\n",
        "# Open the file\n",
        "with open(output_file_path, 'r') as file:\n",
        "    # Read the file content\n",
        "    content = file.read()\n",
        "\n",
        "# Split the content into words\n",
        "words = content.split()\n",
        "\n",
        "# Count word occurrences\n",
        "word_counts = text_processing.count_word_occurrences(words)\n",
        "\n",
        "# Print the five most common words and their occurrences\n",
        "text_processing.print_common_words(word_counts, 5)\n",
        "\n",
        "# Print the five least common words and their occurrences\n",
        "text_processing.print_least_common_words(word_counts, 5)"
      ],
      "metadata": {
        "id": "fOwN7Zwzkai-"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Colaboratory non-working solution"
      ],
      "metadata": {
        "id": "HsWQZtodkksX"
      }
    },
    {
      "cell_type": "code",
      "source": [
        " # prompt: Refactor the code in module created in cell above into a package\n",
        " #        containing at least one module for the cleaning functions, and another\n",
        " #        for the processing functions, and (optionally) one for custom exceptions\n",
        " #         (if you have any). Then refactor main() to use the new package.\n",
        "\n",
        "# Create a directory for the package\n",
        "!mkdir text_processor\n",
        "\n",
        "# Create a file for the cleaning functions\n",
        "%%writefile text_processor/cleaning.py\n",
        "def clean_line(line):\n",
        "    # Convert the line to lowercase\n",
        "    line = line.lower()\n",
        "\n",
        "    # Remove punctuation from the line\n",
        "    line = line.translate(str.maketrans('', '', string.punctuation))\n",
        "\n",
        "    return line\n",
        "\n",
        "# Create a file for the processing functions\n",
        "%%writefile text_processor/processing.py\n",
        "def write_words_to_file(words, output_file):\n",
        "    # Write each word to the output file\n",
        "    for word in words:\n",
        "        output_file.write(word + '\\n')\n",
        "\n",
        "def count_word_occurrences(words):\n",
        "    # Count the occurrences of each word using a dictionary\n",
        "    word_counts = {}\n",
        "    for word in words:\n",
        "        if word in word_counts:\n",
        "            word_counts[word] += 1\n",
        "        else:\n",
        "            word_counts[word] = 1\n",
        "\n",
        "    return word_counts\n",
        "\n",
        "def print_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n most common words and their occurrences\n",
        "    print(f\"{n} most common words:\")\n",
        "    for word, count in sorted_word_counts[:n]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def print_least_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n least common words and their occurrences\n",
        "    print(f\"{n} least common words:\")\n",
        "    for word, count in sorted_word_counts[-n:]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def process_file(input_file_path, output_file_path):\n",
        "    # Open the input file for reading\n",
        "    with open(input_file_path, 'r') as input_file:\n",
        "        # Open the output file for writing\n",
        "        with open(output_file_path, 'w') as output_file:\n",
        "            # Iterate over each line in the input file\n",
        "            for line in input_file:\n",
        "                # Clean the line\n",
        "                cleaned_line = clean_line(line)\n",
        "\n",
        "                # Split the line into words\n",
        "                words = cleaned_line.split()\n",
        "\n",
        "                # Write the words to the output file\n",
        "                write_words_to_file(words, output_file)\n",
        "\n",
        "# Create an __init__.py file to make the directory a package\n",
        "%%writefile text_processor/__init__.py\n",
        "from .cleaning import clean_line\n",
        "from .processing import process_file, count_word_occurrences, print_common_words, print_least_common_words\n",
        "\n",
        "# Refactor main() to use the new package\n",
        "%%writefile main.py\n",
        "import text_processor\n",
        "\n",
        "input_file_path = 'moby_01.txt'\n",
        "output_file_path = 'moby_01_clean.txt'\n",
        "\n",
        "# Process the file\n",
        "text_processor.process_file(input_file_path, output_file_path)\n",
        "\n",
        "# Open the file\n",
        "with open(output_file_path, 'r') as file:\n",
        "    # Read the file content\n",
        "    content = file.read()\n",
        "\n",
        "# Split the content into words\n",
        "words = content.split()\n",
        "\n",
        "# Count word occurrences\n",
        "word_counts = text_processor.count_word_occurrences(words)\n",
        "\n",
        "# Print the five most common words and their occurrences\n",
        "text_processor.print_common_words(word_counts, 5)\n",
        "\n",
        "# Print the five least common words and their occurrences\n",
        "text_processor.print_least_common_words(word_counts, 5)\n",
        "\n",
        "# Run the main script\n",
        "!python main.py\n"
      ],
      "metadata": {
        "id": "m0hvsM1hjh7f",
        "outputId": "c0897f65-ad93-4c41-bc62-a50529c530a0",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "UsageError: Line magic function `%%writefile` not found.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Colaboratory solution broken into cells"
      ],
      "metadata": {
        "id": "LfBSNLcyk0gC"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a directory for the package\n",
        "!mkdir text_processor\n"
      ],
      "metadata": {
        "id": "YpCyY5wlk6NR",
        "outputId": "93991738-7200-42d4-d539-f96affe03a71",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "mkdir: cannot create directory ‘text_processor’: File exists\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a file for the cleaning functions\n",
        "%%writefile text_processor/cleaning.py\n",
        "\n",
        "#### THIS IMPORT WAS ADDED BY AUTHOR\n",
        "import string\n",
        "\n",
        "def clean_line(line):\n",
        "    # Convert the line to lowercase\n",
        "    line = line.lower()\n",
        "\n",
        "    # Remove punctuation from the line\n",
        "    line = line.translate(str.maketrans('', '', string.punctuation))\n",
        "\n",
        "    return line"
      ],
      "metadata": {
        "id": "jdmjh0vulBeM",
        "outputId": "47f8bcd2-9832-4a9d-a0f9-386ddd53cf22",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Overwriting text_processor/cleaning.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "l9SspjwfpPYM"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a file for the processing functions\n",
        "%%writefile text_processor/processing.py\n",
        "\n",
        "#### THIS IMPORT WAS ADDED BY AUTHOR\n",
        "from text_processor.cleaning import clean_line\n",
        "\n",
        "def write_words_to_file(words, output_file):\n",
        "    # Write each word to the output file\n",
        "    for word in words:\n",
        "        output_file.write(word + '\\n')\n",
        "\n",
        "def count_word_occurrences(words):\n",
        "    # Count the occurrences of each word using a dictionary\n",
        "    word_counts = {}\n",
        "    for word in words:\n",
        "        if word in word_counts:\n",
        "            word_counts[word] += 1\n",
        "        else:\n",
        "            word_counts[word] = 1\n",
        "\n",
        "    return word_counts\n",
        "\n",
        "def print_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n most common words and their occurrences\n",
        "    print(f\"{n} most common words:\")\n",
        "    for word, count in sorted_word_counts[:n]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def print_least_common_words(word_counts, n):\n",
        "    # Sort the word counts in descending order\n",
        "    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)\n",
        "\n",
        "    # Print the n least common words and their occurrences\n",
        "    print(f\"{n} least common words:\")\n",
        "    for word, count in sorted_word_counts[-n:]:\n",
        "        print(f\"{word}: {count}\")\n",
        "\n",
        "def process_file(input_file_path, output_file_path):\n",
        "    # Open the input file for reading\n",
        "    with open(input_file_path, 'r') as input_file:\n",
        "        # Open the output file for writing\n",
        "        with open(output_file_path, 'w') as output_file:\n",
        "            # Iterate over each line in the input file\n",
        "            for line in input_file:\n",
        "                # Clean the line\n",
        "                cleaned_line = clean_line(line)\n",
        "\n",
        "                # Split the line into words\n",
        "                words = cleaned_line.split()\n",
        "\n",
        "                # Write the words to the output file\n",
        "                write_words_to_file(words, output_file)\n"
      ],
      "metadata": {
        "id": "7Zbr_CEZlDxY",
        "outputId": "2a497004-5071-4582-9d46-8b158d575c27",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Overwriting text_processor/processing.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an __init__.py file to make the directory a package\n",
        "%%writefile text_processor/__init__.py\n",
        "from .cleaning import clean_line\n",
        "from .processing import process_file, count_word_occurrences, print_common_words, print_least_common_words"
      ],
      "metadata": {
        "id": "QPofFzsXlIdZ",
        "outputId": "4e16ab27-0a45-4421-8868-42a3b2f5b551",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing text_processor/__init__.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Refactor main() to use the new package\n",
        "%%writefile main.py\n",
        "import text_processor\n",
        "\n",
        "input_file_path = 'moby_01.txt'\n",
        "output_file_path = 'moby_01_clean.txt'\n",
        "\n",
        "# Process the file\n",
        "text_processor.process_file(input_file_path, output_file_path)\n",
        "\n",
        "# Open the file\n",
        "with open(output_file_path, 'r') as file:\n",
        "    # Read the file content\n",
        "    content = file.read()\n",
        "\n",
        "# Split the content into words\n",
        "words = content.split()\n",
        "\n",
        "# Count word occurrences\n",
        "word_counts = text_processor.count_word_occurrences(words)\n",
        "\n",
        "# Print the five most common words and their occurrences\n",
        "text_processor.print_common_words(word_counts, 5)\n",
        "\n",
        "# Print the five least common words and their occurrences\n",
        "text_processor.print_least_common_words(word_counts, 5)"
      ],
      "metadata": {
        "id": "WKpSlSM6lOFg",
        "outputId": "72e6b3b2-4866-48c7-dc76-37c34015c9e4",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing main.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Run the main script\n",
        "!python main.py"
      ],
      "metadata": {
        "id": "n5cXVzkglPGH",
        "outputId": "094fcffc-a711-45cf-df30-7395ef216194",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "5 most common words:\n",
            "the: 14\n",
            "and: 9\n",
            "i: 9\n",
            "of: 8\n",
            "is: 7\n",
            "5 least common words:\n",
            "land: 1\n",
            "look: 1\n",
            "at: 1\n",
            "crowds: 1\n",
            "watergazers: 1\n"
          ]
        }
      ]
    }
  ]
}